package org.dromara.common.core.enums;

import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StringUtils;

import java.util.Arrays;


/**
 * @Author 刘武贵
 * @Date 2024/8/15 22:00
 * @Description 功能描述：业务状态枚举
 */
@Getter
@AllArgsConstructor
public enum BusinessStatusEnum {
    /**
     * 已撤销
     */
    CANCEL("cancel", "已撤销"),

    /**
     * 草稿
     */
    DRAFT("draft", "草稿"),

    /**
     * 待审核
     */
    WAITING("waiting", "待审核"),

    /**
     * 已完成
     */
    FINISH("finish", "已完成"),

    /**
     * 已作废
     */
    INVALID("invalid", "已作废"),

    /**
     * 已退回
     */
    BACK("back", "已退回"),

    /**
     * 已终止
     */
    TERMINATION("termination", "已终止");

    /**
     * 状态
     */
    private final String status;

    /**
     * 描述
     */
    private final String desc;

    /**
     * 获取业务状态
     * 根据状态查找业务状态描述
     *
     * @param status 业务状态代码
     * @return 业务状态描述如果找不到匹配的业务状态，返回空字符串
     */
    public static String findByStatus(String status) {
        if (StringUtils.isBlank(status)) {
            return StrUtil.EMPTY;
        }
        // 在BusinessStatusEnum枚举中查找与给定状态代码匹配的业务状态
        return Arrays.stream(BusinessStatusEnum.values())
            .filter(statusEnum -> statusEnum.getStatus().equals(status))
            .findFirst()
            .map(BusinessStatusEnum::getDesc)
            .orElse(StrUtil.EMPTY);
    }

    /**
     * 启动流程校验
     * 检查流程状态是否符合操作要求
     * 本函数的目的是确保在进行某项操作前，流程的状态满足预定的条件
     * 如果状态不符合条件，将抛出异常，阻止后续操作的执行
     *
     * @param status 流程的当前状态
     * @throws ServiceException 如果状态不符合操作条件，抛出业务异常
     */
    public static void checkStartStatus(String status) {
        // 检查流程状态是否为等待审批状态，如果是，则抛出异常
        if (WAITING.getStatus().equals(status)) {
            throw new ServiceException("该单据已提交过申请,正在审批中！");
        } else if (FINISH.getStatus().equals(status)) {
            // 检查流程状态是否为已完成状态，如果是，则抛出异常
            throw new ServiceException("该单据已完成申请！");
        } else if (INVALID.getStatus().equals(status)) {
            // 检查流程状态是否为作废状态，如果是，则抛出异常
            throw new ServiceException("该单据已作废！");
        } else if (TERMINATION.getStatus().equals(status)) {
            // 检查流程状态是否为终止状态，如果是，则抛出异常
            throw new ServiceException("该单据已终止！");
        } else if (StringUtils.isBlank(status)) {
            // 检查流程状态是否为空，如果是，则抛出异常
            throw new ServiceException("流程状态为空！");
        }
    }

    /**
     * 撤销流程校验
     * 检查并处理操作状态
     * 如果状态为撤销、完成、作废、终止或退回，则抛出异常提示用户
     * 如果状态为空字符串，则也抛出异常提示流程状态为空
     *
     * @param status 操作状态，用于判断是否可以继续操作
     * @throws ServiceException 如果状态不符合操作条件，抛出业务异常
     */
    public static void checkCancelStatus(String status) {
        // 判断状态是否为撤销，如果是，则抛出异常
        if (CANCEL.getStatus().equals(status)) {
            throw new ServiceException("该单据已撤销！");
        } else if (FINISH.getStatus().equals(status)) {
            // 判断状态是否为完成，如果是，则抛出异常
            throw new ServiceException("该单据已完成申请！");
        } else if (INVALID.getStatus().equals(status)) {
            // 判断状态是否为作废，如果是，则抛出异常
            throw new ServiceException("该单据已作废！");
        } else if (TERMINATION.getStatus().equals(status)) {
            // 判断状态是否为终止，如果是，则抛出异常
            throw new ServiceException("该单据已终止！");
        } else if (BACK.getStatus().equals(status)) {
            // 判断状态是否为退回，如果是，则抛出异常
            throw new ServiceException("该单据已退回！");
        } else if (StringUtils.isBlank(status)) {
            // 判断状态是否为空字符串，如果是，则抛出异常
            throw new ServiceException("流程状态为空！");
        }
    }

    /**
     * 驳回流程校验
     * 检查并根据单据状态抛出异常
     * 此方法主要用于在操作执行前验证单据的状态是否允许操作
     * 如果单据处于退回、完成申请、作废、终止或撤销状态，则抛出ServiceException异常，提示用户不能进行操作
     * 如果传入的状态为空或空白字符串，也会抛出异常提示流程状态为空
     *
     * @param status 单据的状态，用于判断是否允许继续操作
     * @throws ServiceException 如果单据处于不允许操作的状态或状态为空，则抛出此异常
     */
    public static void checkBackStatus(String status) {
        // 检查单据状态是否已退回，如果是，则抛出异常
        if (BACK.getStatus().equals(status)) {
            throw new ServiceException("该单据已退回！");
        }
        // 检查单据状态是否已完成申请，如果是，则抛出异常
        else if (FINISH.getStatus().equals(status)) {
            throw new ServiceException("该单据已完成申请！");
        }
        // 检查单据状态是否已作废，如果是，则抛出异常
        else if (INVALID.getStatus().equals(status)) {
            throw new ServiceException("该单据已作废！");
        }
        // 检查单据状态是否已终止，如果是，则抛出异常
        else if (TERMINATION.getStatus().equals(status)) {
            throw new ServiceException("该单据已终止！");
        }
        // 检查单据状态是否已撤销，如果是，则抛出异常
        else if (CANCEL.getStatus().equals(status)) {
            throw new ServiceException("该单据已撤销！");
        }
        // 检查传入的状态是否为空或空白字符串，如果是，则抛出异常
        else if (StringUtils.isBlank(status)) {
            throw new ServiceException("流程状态为空！");
        }
    }

    /**
     * 作废,终止流程校验
     * 该方法用于确保业务流程的状态符合预期，防止对已完成、作废或终止的单据进行进一步操作
     *
     * @param status 待检查的流程状态
     * @throws ServiceException 如果状态为完成、作废、终止或为空，则抛出业务逻辑异常
     */
    public static void checkInvalidStatus(String status) {
        // 检查状态是否为完成，如果是，则抛出异常提示该单据已完成申请
        if (FINISH.getStatus().equals(status)) {
            throw new ServiceException("该单据已完成申请！");
        }
        // 检查状态是否为作废，如果是，则抛出异常提示该单据已作废
        else if (INVALID.getStatus().equals(status)) {
            throw new ServiceException("该单据已作废！");
        }
        // 检查状态是否为终止，如果是，则抛出异常提示该单据已终止
        else if (TERMINATION.getStatus().equals(status)) {
            throw new ServiceException("该单据已终止！");
        }
        // 检查状态是否为空或未定义，如果是，则抛出异常提示流程状态为空
        else if (StringUtils.isBlank(status)) {
            throw new ServiceException("流程状态为空！");
        }
    }
}

